﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;

using TinyLib.Input;
using TinyLib.Sprite;
using TinyLib.Entity;

namespace GodBuilderIdea
{
    public class Tribe : Entity
    {
        public enum TribeType
        {
            COLD,
            WARM,
            SEA
        }

        public TribeType m_type;
        public int m_amount = 1;
        int m_amount_limit = 5; //should be an uneven number
        SpriteFont m_font;
        public bool m_split = false;
        public bool m_selected = false;

        EnvTile.EnvironmentType m_preferred_type;
        EnvTile.EnvironmentType m_harmful_type;
        public int m_tile_index_pos = 0;

        public int tile_width = 20;
        public int tile_height = 10;
        String m_player_name;

        Vector2 m_direction = new Vector2(1, 0);
        Sprite m_selected_tribe;

        public Tribe(Game game, SpriteBatch sprite_batch, TribeType type, String player_name)
            : base(game, sprite_batch)
        {
            m_type = type;
            KillMe = false;
            Initialize();
            m_player_name = player_name;
        }

        public override void Initialize()
        {
            if (m_type == TribeType.COLD)
            {
                texture2D = Game.Content.Load<Texture2D>("images/cold_tribe");
                m_preferred_type = EnvTile.EnvironmentType.SNOW;
                m_harmful_type = EnvTile.EnvironmentType.DESERT;
            }
            else if (m_type == TribeType.WARM)
            {
                texture2D = Game.Content.Load<Texture2D>("images/warm_tribe");
                m_preferred_type = EnvTile.EnvironmentType.DESERT;
                m_harmful_type = EnvTile.EnvironmentType.SNOW;
            }
            else if (m_type == TribeType.SEA)
            {
                texture2D = Game.Content.Load<Texture2D>("images/water_tribe");
                m_preferred_type = EnvTile.EnvironmentType.WATER;
                m_harmful_type = EnvTile.EnvironmentType.SWAMP;
            }

            m_font = Game.Content.Load<SpriteFont>("Font");

            Texture2D tex = Game.Content.Load<Texture2D>("images/selected_tribe_tile_glow");
            m_selected_tribe = new Sprite(Spritebatch, tex, Game);

            base.Initialize();
        }

        public List<int> GetTwoAdjacent(List<EnvTile> tile_list)
        {
            List<int> adjacentTileIdxs = new List<int>();

            int left_idx = -1;
            int right_idx = -1;
            int top_idx = -1;
            int bot_idx = -1;

            int top_left_idx = -1;
            int top_right_idx = -1;
            int bot_left_idx = -1;
            int bot_right_idx = -1;

            if (!tile_list[m_tile_index_pos].left) { left_idx = m_tile_index_pos - tile_height;  adjacentTileIdxs.Add(left_idx); }//left 
            if (!tile_list[m_tile_index_pos].right) { right_idx = m_tile_index_pos + tile_height; adjacentTileIdxs.Add(right_idx); }//right
            if (!tile_list[m_tile_index_pos].top) { top_idx = m_tile_index_pos - 1; adjacentTileIdxs.Add(top_idx); }//top
            if (!tile_list[m_tile_index_pos].bottom) { bot_idx = m_tile_index_pos + 1; adjacentTileIdxs.Add(bot_idx); }//bottom
            if (!tile_list[m_tile_index_pos].left && !tile_list[m_tile_index_pos].top) { top_left_idx = m_tile_index_pos - tile_height - 1; adjacentTileIdxs.Add(top_left_idx); } //topleft
            if (!tile_list[m_tile_index_pos].right && !tile_list[m_tile_index_pos].top) { top_right_idx = m_tile_index_pos + tile_height - 1; adjacentTileIdxs.Add(top_right_idx); }//topright
            if (!tile_list[m_tile_index_pos].left && !tile_list[m_tile_index_pos].bottom) { bot_left_idx = m_tile_index_pos - tile_height + 1; adjacentTileIdxs.Add(bot_left_idx); }//botleft
            if (!tile_list[m_tile_index_pos].right && !tile_list[m_tile_index_pos].bottom) { bot_right_idx = m_tile_index_pos + tile_height + 1; adjacentTileIdxs.Add(bot_right_idx); } //botright

            if (top_idx >= 0)
            {
                if (!tile_list[top_idx].top) { adjacentTileIdxs.Add(m_tile_index_pos - 2); } //top2mid
                if (!tile_list[top_idx].top && !tile_list[top_idx].left) { adjacentTileIdxs.Add(m_tile_index_pos - tile_height - 2); } //top2midleft
                if (!tile_list[top_idx].top && !tile_list[top_idx].right) { adjacentTileIdxs.Add(m_tile_index_pos + tile_height - 2); } //top2midright
                if (top_left_idx >= 0) { if (!tile_list[top_left_idx].top) { adjacentTileIdxs.Add(m_tile_index_pos - (tile_height * 2) - 2); } } //top2left
                if (top_right_idx >= 0) { if (!tile_list[top_right_idx].top) { adjacentTileIdxs.Add(m_tile_index_pos + (tile_height * 2) - 2); } } //top2right
            }
            if (bot_idx >= 0)
            {
                if (!tile_list[bot_idx].bottom) { adjacentTileIdxs.Add(m_tile_index_pos + 2); } //bot2mid
                if (!tile_list[bot_idx].bottom && !tile_list[bot_idx].left) { adjacentTileIdxs.Add(m_tile_index_pos - tile_height + 2); } //bot2midleft
                if (!tile_list[bot_idx].bottom && !tile_list[bot_idx].right) { adjacentTileIdxs.Add(m_tile_index_pos + tile_height + 2); }  //bot2midright
                if (bot_left_idx >= 0) { if (!tile_list[bot_left_idx].bottom) { adjacentTileIdxs.Add(m_tile_index_pos - (tile_height * 2) + 2); } } //bot2left
                if (bot_right_idx >= 0) { if (!tile_list[bot_right_idx].bottom){ adjacentTileIdxs.Add(m_tile_index_pos + (tile_height * 2) + 2); } }//bot2right
            
                }
            if (left_idx >= 0)
            {
                if (!tile_list[left_idx].left) { adjacentTileIdxs.Add(m_tile_index_pos - (tile_height * 2)); } //left2mid
                if (!tile_list[left_idx].left && !tile_list[left_idx].top) { adjacentTileIdxs.Add(m_tile_index_pos - (tile_height * 2) - 1); } //left2midtop
                if (!tile_list[left_idx].left && !tile_list[left_idx].bottom) { adjacentTileIdxs.Add(m_tile_index_pos - (tile_height * 2) + 1); } //left2midbot
            }
            if (right_idx >= 0)
            {
                if (!tile_list[right_idx].right) { adjacentTileIdxs.Add(m_tile_index_pos + (tile_height * 2)); } //right2mid
                if (!tile_list[right_idx].right && !tile_list[right_idx].top) { adjacentTileIdxs.Add(m_tile_index_pos + (tile_height * 2) - 1); } //right2midtop
                if (!tile_list[right_idx].right && !tile_list[right_idx].bottom) { adjacentTileIdxs.Add(m_tile_index_pos + (tile_height * 2) + 1); } //right2midbot
            }

            //there is some fringe case of an index becoming negative
            //foreach (int idx in adjacentTileIdxs)
            for (int i = 0; i < adjacentTileIdxs.Count; i++)
            {
                if (adjacentTileIdxs[i] < 0)
                {
                    adjacentTileIdxs[i] = 0;
                }
            }

            return adjacentTileIdxs;
        }

        public List<int> GetAdjacent(List<EnvTile> tile_list)
        {
            List<int> adjacentTileIdxs = new List<int>();

            if (!tile_list[m_tile_index_pos].left) { adjacentTileIdxs.Add(m_tile_index_pos - tile_height); }//left 
            if (!tile_list[m_tile_index_pos].right) { adjacentTileIdxs.Add(m_tile_index_pos + tile_height); }//right
            if (!tile_list[m_tile_index_pos].top) { adjacentTileIdxs.Add(m_tile_index_pos - 1); }//up
            if (!tile_list[m_tile_index_pos].bottom) { adjacentTileIdxs.Add(m_tile_index_pos + 1); }//down
            if (!tile_list[m_tile_index_pos].left && !tile_list[m_tile_index_pos].top) { adjacentTileIdxs.Add(m_tile_index_pos - tile_height - 1); } //topleft
            if (!tile_list[m_tile_index_pos].right && !tile_list[m_tile_index_pos].top) { adjacentTileIdxs.Add(m_tile_index_pos + tile_height - 1); }//topright
            if (!tile_list[m_tile_index_pos].left && !tile_list[m_tile_index_pos].bottom) { adjacentTileIdxs.Add(m_tile_index_pos - tile_height + 1); }//botleft
            if (!tile_list[m_tile_index_pos].right && !tile_list[m_tile_index_pos].bottom) { adjacentTileIdxs.Add(m_tile_index_pos + tile_height + 1); } //botright

            return adjacentTileIdxs;
        }

        public void DoSomeActions(List<EnvTile> tile_list, List<Player> player_list)
        {
            List<int> adjacentTileIdxs = new List<int>();
            if (!tile_list[m_tile_index_pos].left) { adjacentTileIdxs.Add(m_tile_index_pos - tile_height); }//left 
            if (!tile_list[m_tile_index_pos].right) { adjacentTileIdxs.Add(m_tile_index_pos + tile_height); }//right
            if (!tile_list[m_tile_index_pos].top) { adjacentTileIdxs.Add(m_tile_index_pos - 1); }//up
            if (!tile_list[m_tile_index_pos].bottom) { adjacentTileIdxs.Add(m_tile_index_pos + 1); }//down
            if (!tile_list[m_tile_index_pos].left && !tile_list[m_tile_index_pos].top) { adjacentTileIdxs.Add(m_tile_index_pos - tile_height - 1); } //topleft
            if (!tile_list[m_tile_index_pos].right && !tile_list[m_tile_index_pos].top) { adjacentTileIdxs.Add(m_tile_index_pos + tile_height - 1); }//topright
            if (!tile_list[m_tile_index_pos].left && !tile_list[m_tile_index_pos].bottom) { adjacentTileIdxs.Add(m_tile_index_pos - tile_height + 1); }//botleft
            if (!tile_list[m_tile_index_pos].right && !tile_list[m_tile_index_pos].bottom) { adjacentTileIdxs.Add(m_tile_index_pos + tile_height + 1); } //botright

            bool have_moved = false;
            bool other_tribes_on_tile = false;

            foreach (Player p in player_list)
            {
                if (p.m_goal.m_player_name != m_player_name)
                {
                    foreach (Tribe t in p.m_tribes)
                    {
                        if (t.m_tile_index_pos == m_tile_index_pos)
                        {
                            other_tribes_on_tile = true;
                            break;
                        }
                    }
                }
            }

            if (tile_list[m_tile_index_pos].m_type == EnvTile.EnvironmentType.DEFAULT)
            {
                //nothing happens
                //should they even be on the map before it is covered? that could be a progress thing
            }
            else if (other_tribes_on_tile)
            {
                //stay and fight, don't move
                have_moved = true;
            }
            else if (tile_list[m_tile_index_pos].m_type == m_preferred_type)
            {
                m_amount++;
                if (m_amount > m_amount_limit)
                {
                    //split tribe up
                    m_split = true;
                }

                foreach (int tileIdx in adjacentTileIdxs)
                {
                    if (tile_list[tileIdx].m_type != m_preferred_type)
                    {
                        m_tile_index_pos = tileIdx;
                        position = tile_list[tileIdx].position;
                        have_moved = true;
                        break;
                    }
                }
            }
            else if (tile_list[m_tile_index_pos].m_type == m_harmful_type)
            {
                foreach (int tileIdx in adjacentTileIdxs)
                {
                    if (tile_list[tileIdx].m_type != m_harmful_type
                        && tile_list[tileIdx].m_type != EnvTile.EnvironmentType.LAVA
                        && tile_list[tileIdx].m_type != EnvTile.EnvironmentType.MOUNTAIN)
                    {
                        m_tile_index_pos = tileIdx;
                        position = tile_list[tileIdx].position;
                        have_moved = true;
                        break;
                    }
                }

                if (!have_moved)
                {
                    m_amount--;
                    if (m_amount <= 0)
                    { KillMe = true; }
                }
            }
            else if (tile_list[m_tile_index_pos].m_type == EnvTile.EnvironmentType.LAVA)
            {
                m_amount=0;
                KillMe = true;
            }
         
            if (!have_moved)
            {

                Random rand = new Random(); //make directions system instead, so they change direction when they meet difficulties
                int dir = rand.Next(1, 5);
                if (dir == 1) //left
                {
                    if (!tile_list[m_tile_index_pos].left)
                    {
                        if (tile_list[m_tile_index_pos - tile_height].m_type != EnvTile.EnvironmentType.MOUNTAIN
                            && tile_list[m_tile_index_pos - tile_height].m_type != EnvTile.EnvironmentType.LAVA
                            && tile_list[m_tile_index_pos - tile_height].m_type != m_harmful_type)
                        {
                            m_tile_index_pos -= tile_height;
                        }
                    }
                }
                else if (dir == 2) //right
                {
                    if (!tile_list[m_tile_index_pos].right)
                    {
                        if (tile_list[m_tile_index_pos + tile_height].m_type != EnvTile.EnvironmentType.MOUNTAIN
                            && tile_list[m_tile_index_pos + tile_height].m_type != EnvTile.EnvironmentType.LAVA
                            && tile_list[m_tile_index_pos + tile_height].m_type != m_harmful_type)
                        {
                            m_tile_index_pos += tile_height;
                        }
                    }
                }
                else if (dir == 3) //up
                {
                    if (!tile_list[m_tile_index_pos].top)
                    {
                        if (tile_list[m_tile_index_pos - 1].m_type != EnvTile.EnvironmentType.MOUNTAIN
                            && tile_list[m_tile_index_pos - 1].m_type != EnvTile.EnvironmentType.LAVA
                            && tile_list[m_tile_index_pos - 1].m_type != m_harmful_type)
                        {
                            m_tile_index_pos -= 1;
                        }
                    }
                }
                else //down
                {
                    if (!tile_list[m_tile_index_pos].bottom)
                    {
                        if (tile_list[m_tile_index_pos + 1].m_type != EnvTile.EnvironmentType.MOUNTAIN
                            && tile_list[m_tile_index_pos + 1].m_type != EnvTile.EnvironmentType.LAVA
                            && tile_list[m_tile_index_pos + 1].m_type != m_harmful_type)
                        {
                            m_tile_index_pos += 1;
                        }
                    }
                }

                position = tile_list[m_tile_index_pos].position;
                // }
            }

                foreach (Player p in player_list){
                    foreach (Tribe t in p.m_tribes){
                        if (t.m_tile_index_pos == m_tile_index_pos
                            && t.m_player_name != m_player_name){
                            t.m_amount--; 
                            if (t.m_amount <= 0) { t.KillMe = true; }
                            m_amount--;
                            if (m_amount <= 0) { KillMe = true; }
                        }
                    }
                }
        }

        public override void Update(GameTime gameTime)
        {
            base.Update(gameTime);
        }

        public override void Draw(GameTime gameTime)
        {
            if (m_selected)
            {
                m_selected_tribe.position = position;
                m_selected_tribe.Draw(gameTime);
            }
            base.Draw(gameTime);
            Spritebatch.DrawString(m_font, "" + m_amount, position, Color.Red);
        }
    }
}
